/* main.c */
#include "app_inc.h"

/*
* Application Function Declerations.
*/
/* LED. */
void LED_Configuration(void);
void LED_LightOn(uint32_t ledIdx);
void LED_LightOff(uint32_t ledIdx);
void LED_LightSwitch(uint32_t ledIdx);
/* Ticker. */
void Ticker_Configuration(uint32_t tickersPerSecond);
void Ticker_Start(void);
void Ticker_Pause(void);

/*
* Application Entry.
*/
int main(void)
{
    BSP_InitStdioUART(115200U);

    printf("\r\n\r\n# Systick_TickerInterrupt Exampler #\r\n");

    /* Initialize the application. */
    printf("# Initializing ...\r\n");
    
    LED_Configuration();
    Ticker_Configuration(200U); /* 200 tickers per second. 1 ticker = 5ms. */
    
    printf("# Ready.\r\n");
    
    /* Print the user guide. */
    printf("Press any key to toggle the ticker ...\r\n");
    
    while (1)
    {
        getchar();
        Ticker_Start();
        printf("Ticker_Start()\r\n");
        getchar();
        Ticker_Pause();
        printf("Ticker_Pause()\r\n");
    }
}

/*
 * Interrupt Service Routine.
 */
volatile uint32_t gTickerCounter[3] = {0};
const uint32_t gLedSwitchTickers[3] = {100U, 200U, 400U};
void SysTick_Handler(void)
{
    uint32_t i;
    
    for (i = 0U; i < 3U; i++)
    {
        if (gTickerCounter[i] >= gLedSwitchTickers[i])
        {
            gTickerCounter[i] = 0U;
            LED_LightSwitch(i); /* Switch the LED. */
        }
        gTickerCounter[i]++;
    }
}

/*
 * Application Functions.
 */
void LED_Configuration(void)
{
    GPIO_InitPara GPIO_InitStructure;
    RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOD,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_11 | GPIO_PIN_12| GPIO_PIN_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
    GPIO_Init(GPIOD,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
    GPIO_Init(GPIOD,&GPIO_InitStructure);
}

const uint16_t gLedPins[] = {GPIO_PIN_11, GPIO_PIN_12, GPIO_PIN_13}; 

void LED_LightOn(uint32_t ledIdx)
{
    if (ledIdx >= sizeof(gLedPins)/sizeof(gLedPins[0]))
    {
        return;
    }
    GPIO_SetBits(GPIOD, gLedPins[ledIdx]);
}

void LED_LightOff(uint32_t ledIdx)
{
    if (ledIdx >= sizeof(gLedPins)/sizeof(gLedPins[0]))
    {
        return;
    }
    GPIO_ResetBits(GPIOD, gLedPins[ledIdx]);
}

void LED_LightSwitch(uint32_t ledIdx)
{
    BitState value;

    if (ledIdx >= sizeof(gLedPins)/sizeof(gLedPins[0]))
    {
        return;
    }
    value =  (BitState)(1-GPIO_ReadOutputBit(GPIOD, gLedPins[ledIdx]));
    GPIO_WriteBit(GPIOD, gLedPins[ledIdx], value);
}

void Ticker_Configuration(uint32_t tickersPerSecond)
{
    SysTick_Config(SystemCoreClock / tickersPerSecond);
    NVIC_SetPriority(SysTick_IRQn, 0x00);
    
    SysTick->LOAD  = (uint32_t)(SystemCoreClock / tickersPerSecond - 1UL); /* set reload register */
    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
    SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | /* Select the clock source. */
                   SysTick_CTRL_TICKINT_Msk;      /* Enable SysTick IRQ. */
}

void Ticker_Start(void)
{
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}

void Ticker_Pause(void)
{
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

/* EOF. */
